package org.brisling.common.crypt.strategy.impl;

import java.security.InvalidKeyException;
import java.security.Key;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;

import org.brisling.common.crypt.strategy.base.AbstractCrypt;
import org.brisling.common.crypt.strategy.inf.crypt;
import org.brisling.common.util.RSAUtils;

/**
 * 
 * <p>Title: RSACryptImpl</p>
 * <p>Description: RSA加密解密实现类</p>
 * <p>Company: tongking</p>
 * @author jackson wang
 * @since 1.0
 * @version 1.0
 * @date 2017年5月18日 下午3:30:44
 */
public class RSACryptImpl extends AbstractCrypt implements crypt{
	
	
	public RSACryptImpl(){
		super("RSA");
	}

	@Override
	public String encrypt(String data,Key key) {
		// TODO Auto-generated method stub
		String mi = "";
		if( (key!=null) && (key instanceof RSAPublicKey) ){
			
			RSAPublicKey pk = (RSAPublicKey)key;
			try {
				cipher.init(Cipher.ENCRYPT_MODE, pk);
			} catch (InvalidKeyException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			// 模长
			int key_len = pk.getModulus().bitLength() / 8;
			// 加密数据长度 <= 模长-11
			String[] datas = RSAUtils.splitString(data, key_len - 11);
			
			//如果明文长度大于模长-11则要分组加密
			for (String s : datas) {
				try {
					mi += RSAUtils.bcd2Str(cipher.doFinal(s.getBytes()));
				} catch (IllegalBlockSizeException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (BadPaddingException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		return mi;
	}

	@Override
	public String decrypt(String data,Key key) {
		// TODO Auto-generated method stub
		
		if( (key!=null) && (key instanceof RSAPrivateKey) ){
			
			RSAPrivateKey privateKey = (RSAPrivateKey)key;
			try {
				cipher.init(Cipher.DECRYPT_MODE, privateKey);
			} catch (InvalidKeyException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			//模长
			int key_len = privateKey.getModulus().bitLength() / 8;
			byte[] bytes = data.getBytes();
			byte[] bcd = RSAUtils.ASCII_To_BCD(bytes, bytes.length);
			System.err.println(bcd.length);
			//如果密文长度大于模长则要分组解密
			String ming = "";
			byte[][] arrays = RSAUtils.splitArray(bcd, key_len);
			for(byte[] arr : arrays){
				try {
					ming += new String(cipher.doFinal(arr));
				} catch (IllegalBlockSizeException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (BadPaddingException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			return ming;
		}
		return null;
	}
	
	
	
}
